package webjoch.wrappers;

import java.util.ArrayList;

import com.rsbuddy.script.util.Filter;
import com.rsbuddy.script.wrappers.Tile;

import webjoch.Main;
import webjoch.methods.Links;
import webjoch.misc.PaintMap;
/**
 * 
 * @author Webjoch
 *
 */
public class Explorer{
	private Tile destination;
	private ArrayList<Link> path = new ArrayList<Link>();
	private ArrayList<Link> checkedLinks = new ArrayList<Link>();
	
	public Explorer(Room room, Tile destination){
		this.destination = destination;
		findPath(room, destination);
		PaintMap.lastPath = getPath();
	}
	/**
	 * Gets the first possible link
	 * @return link
	 */
	public Link getNext(){
		Link[] path = getPath();
		for (int i = 0; i < path.length; i++){
			if (path[i].getRoom() == null) continue;
			if (path[i].getRoom().inRoom() && i < path.length){
				return path[i];
			} 
		}
		return null;
	}
	
	
	/**
	 * Get the generated path to the destination
	 * @return all links in the path
	 */
	public Link[] getPath(){
		return path.toArray(new Link[path.size()]);
	}
	
	/**
	 * Find a path in the dungeon to the given destination
	 * @param room the start room
	 * @param destination the destination
	 * @return returns true if the path is successfully generated
	 */
	public boolean findPath(Room room, Tile destination){
		try{
			if (room == null) return false;
			if (room.getArea().contains(destination)) return true;
			
			Link[] links = Links.getRoomLinks(room, new Filter<Link>(){
				public boolean accept(Link l){
					return !checkedLinks.contains(l);
				}
			});
			if (links.length > 1){
				path.add(new Link(null, null, null));
			}
			for (Link link : links){
				checkLink(link);
				path.add(link);
				if (findPath(link.getLinkedRoom(), destination)) return true;
			}
			
			int index = 0;
			Room newRoom = null;
			int length = getPath().length - 1;
			for (int i = 0; i < getPath().length; i++){
				index = length - i;
				if (getPath()[index].getRoom() == null){
					path.remove(index);
					break;
				}
				newRoom = getPath()[index].getRoom();
				path.remove(index);
			}
			if (findPath(newRoom, destination)) return true;
		}catch(ArrayIndexOutOfBoundsException e){
			System.out.println("ArrayIndexOutOfBoundsException");
		}
		return false;
	}

	/**
	 * Gets the given destination
	 * @return the destination
	 */
	public Tile getDestination(){
		return destination;
	}
	
	public void checkLink(Link link1){
		checkedLinks.add(link1);
		for (Link link2 : Main.getDungeon().getMap()){
			if (link2.getRoom().getLocation().equals(link1.getLinkedRoom().getLocation())){
				if (link1.getRotation() == Door.Rotation.NORTH && link2.getRotation() == Door.Rotation.SOUTH) checkedLinks.add(link2);
				if (link1.getRotation() == Door.Rotation.WEST && link2.getRotation() == Door.Rotation.EAST) checkedLinks.add(link2);
				if (link1.getRotation() == Door.Rotation.SOUTH && link2.getRotation() == Door.Rotation.NORTH) checkedLinks.add(link2);
				if (link1.getRotation() == Door.Rotation.EAST && link2.getRotation() == Door.Rotation.WEST) checkedLinks.add(link2);
			}
		}
	}
	
	public int getRoomDistance(){
		return path.size();
	}
}












